#include "scanner.h"

/*** Constructor ***/
Scanner::Scanner()
{
	value = 0;
	x = 0;
	y = 0;
}

/*** Get this scanner's value ***/
unsigned char Scanner::getMemory()
{
	return value;
}

/*** Read the value off the parent surface ***/
void Scanner::readValue()
{
	if(x < surface->getWidth() && y < surface->getHeight())
		value = surface->getSquareValue(x, y);
	else
		value = 0;
}

/*** Write the value onto the parent surface ***/
void Scanner::writeValue()
{
	if(x < surface->getWidth() && y < surface->getHeight())
		surface->setSquareValue(x, y, value);
}

/*** Set this scanner's surface ***/
void Scanner::setSurface(Surface* p_surface)
{
	surface = p_surface;
}

/*** Get this scanner's surface ***/
Surface* Scanner::getSurface()
{
	return surface;
}

/*** Set this scanner's x-coordinate ***/
void Scanner::setX(unsigned int px)
{
	x = (px % surface->getWidth());
	readValue();
}

/*** Get this scanner's x-coordinate ***/
unsigned int Scanner::getX()
{
	return x;
}

/*** Set this scanner's y-coordinate ***/
void Scanner::setY(unsigned int py)
{
	y = (py % 32768);
	readValue();
}

/*** Get this scanner's y-coordinate ***/
unsigned int Scanner::getY()
{
	return y;
}

/*** Move horizontally to X(B) ***/
void Scanner::moveHorizontally(Scanner beta)
{
	setX(beta.getX());
}

/*** Move horizontally to X = n ***/
void Scanner::moveHorizontally(unsigned int px)
{
	setX(px);
}

/*** Move vertically to Y(B) ***/
void Scanner::moveVertically(Scanner beta)
{
	setY(beta.getY());
}

/*** Move vertically to Y = n ***/
void Scanner::moveVertically(unsigned int py)
{
	setY(py);
}

/*** Move to surface and position of B ***/
void Scanner::moveToScannerLocation(Scanner beta)
{
	surface = beta.getSurface();
	setX(beta.getX());
	setY(beta.getY());
}

/*** Move this scanner up n squares ***/
void Scanner::moveUp()
{
	setY(y + 1);
}

/*** Move this scanner down n squares ***/
void Scanner::moveDown()
{
	setY(y - 1);
}

/*** Move this scanner right n squares ***/
void Scanner::moveRight()
{
	setX(x + 1);
	if(x == 0)
		moveDown();
}

/*** Move this scanner left n squares ***/
void Scanner::moveLeft()
{
	if(getX() > 0)
		setX(x - 1);
	else
	{
		setX(surface->getWidth() - 1);
		moveUp();
	}
}

/*** Move one square according to n(B) ***/
void Scanner::moveAccordingToScanner(Scanner beta)
{
			if(beta.getMemory() == 4)	moveUp();
	else	if(beta.getMemory() == 5)	moveRight();
	else	if(beta.getMemory() == 6)	moveDown();
	else	if(beta.getMemory() == 7)	moveLeft();
}

/*** Write the number n ***/
void Scanner::writeNumber(unsigned char pValue)
{
	value = pValue;
	writeValue();
}

/*** Write the number n(B) ***/
void Scanner::writeNumber(Scanner beta)
{
	writeNumber(beta.getMemory());
}

/*** Write K(n(B)) ***/
void Scanner::writeComplement(Scanner beta)
{
	writeNumber((~beta.getMemory()) & 7);
}

/*** Exchange n(A) and n(B) ***/
void Scanner::exchangeNumber(Scanner beta)
{
	unsigned char my_val = value;
	writeNumber(beta.getMemory());
	beta.writeNumber(my_val);
}

/*** Bit-by-bit OR by n(B) ***/
void Scanner::orNumber(Scanner beta)
{
	orNumber(beta.getMemory());
}

/*** Bit-by-bit OR n ***/
void Scanner::orNumber(unsigned char pValue)
{
	value = value | pValue;
	writeValue();
}

/*** Bit-by-bit AND by n(B) ***/
void Scanner::andNumber(Scanner beta)
{
	andNumber(beta.getMemory());
}

/*** Bit-by-bit AND n ***/
void Scanner::andNumber(unsigned char pValue)
{
	value = value & pValue;
	writeValue();
}

/*** Add n(B) ***/
void Scanner::addNumber(Scanner beta)
{
	addNumber(beta.getMemory());
}

/*** Add n ***/
void Scanner::addNumber(unsigned char pValue)
{
	unsigned char result = value + pValue;
	result %= 8;
	value = result;
	writeValue();
}

/*** Subtract n(B) ***/
void Scanner::subtractNumber(Scanner beta)
{
	subtractNumber(beta.getMemory());
}

/*** Subtract n ***/
void Scanner::subtractNumber(unsigned char pValue)
{
	unsigned char result = value - pValue;
	result %= 8;
	value = result;
	writeValue();
}

/*** Multiply by n(B) ***/
void Scanner::multiplyNumber(Scanner beta)
{
	multiplyNumber(beta.getMemory());
}

/*** Multiply by n ***/
void Scanner::multiplyNumber(unsigned char pValue)
{
	unsigned char result = value * pValue;
	result %= 8;
	value = result;
	writeValue();
}

/*** Divide by n(B) ***/
void Scanner::divideNumber(Scanner beta)
{
	divideNumber(beta.getMemory());
}

/*** Divide by n ***/
void Scanner::divideNumber(unsigned char pValue)
{
	unsigned char result = value / pValue;
	result %= 8;
	value = result;
	writeValue();
}

/*** Set memory to n(B) ***/
void Scanner::setMemory(Scanner beta)
{
	setMemory(beta.getMemory());
}

/*** Set memory to n ***/
void Scanner::setMemory(unsigned char pValue)
{
	value = pValue;
}

/*** Deconstructor ***/
Scanner::~Scanner()
{
}
